Fix vendored Hatch running a planted hatch (#613) - #617
Mikola Lysenko (mikolalysenko) wants to merge 2 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
Vendoring a Hatch project whose environments depend on the patched package checks `hatch --version` from inside the project. The probe spawned the bare name `hatch`, so with a relative PATH entry (`.` or an empty component) it ran a `hatch` file committed to the scanned repository: arbitrary code execution from a checkout. The probe now looks `hatch` up on absolute PATH entries only, through the same resolve_tool helper every other in-project spawn uses, and runs the resolved path. When no such `hatch` exists the run takes the existing "requires Hatch >=1.2 on PATH" refusal. Fixes #613 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
|
[agent] CI note:
I'll re-run the failed job once when the workflow's last job finishes. Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e7466ea. Configure here.
|
[burn-down agent] Labeled Ready for review at
Generated by Claude Code |
|
Reviewed The probe now uses the shared absolute-PATH resolver and spawns the resolved executable, preserving the existing version refusal, cwd, stdin and timeout behavior. 27 focused checks passed: 8 Hatch tests, 15 process-helper tests and 4 independent gate controls. Native Hatch 1.18.1 worked with relative PATH entries and planted checkout executables/Python modules; Hatch 1.0.0 retained its expected refusal. Exact-head CI: 476 successful checks, 7 skipped, none pending or failed; all workflows completed. Bugbot is clean, no review threads remain unresolved, and the branch merges cleanly with current Local validation ran on macOS; Linux/Windows are covered by the completed CI runs. Human approval is still required. |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #613
Summary
Vendoring a Hatch project whose environments depend on the patched package no longer runs a
hatchexecutable committed to the scanned repository. Thehatch --versionprobe now resolveshatchon absolutePATHentries only and spawns the resolved path, as every other in-project spawn already does.Root cause
require_environment_context_supportincrates/socket-patch-core/src/vendor/pypi_hatch.rsspawned a bareCommand::new("hatch")withcurrent_dir(root). A relativePATHentry (.or an empty component) resolves against the child's cwd, so the scan executed<project>/hatch. This was the last production bare-name spawn in core/CLI. The others go throughutils::process::resolve_tool, which skips relative entries.Change
require_environment_context_supportdelegates to a newrequire_environment_context_support_with(root, var), which takes an injected environment reader for tests.hatchwithresolve_tool_withand spawns it throughprocess::command_for. The cwd, null stdin,kill_on_dropand 10 s timeout are unchanged.hatchis found, the run takes the existingpypi_hatch_unsupported"requires Hatch >=1.2 on PATH" refusal.resolve_toolnow listshatchamong the tools it serves.npm/,pypi/,gem/don't spawn Hatch).Test evidence
vendor::pypi_hatch::tests::planted_hatch_in_the_project_is_never_executed: plantedhatchin the project,PATH=., empty, and:/nonexistent. Asserts it never runs and the result ispypi_hatch_unsupportedplanted hatch ran with PATH="."vendor::pypi_hatch::tests::hatch_on_an_absolute_path_entry_passes_the_version_gate: ahatchon an absolutePATHdir is run and passes the >=1.2 gateCommands run locally:
cargo test -p socket-patch-core --lib vendor::pypi_hatch: 8 passed.cargo clippy --workspace --all-features -- -D warnings: clean.SOCKET_PATCH_HATCH_E2E_REQUIRED=1 SOCKET_PATCH_HATCH_E2E_VERSION=1.18.1 cargo test -p socket-patch-cli --all-features --test e2e_vex_build -- --ignored hatch::: 4 passed.1.0.0: 4 passed.cargo test --workspace --all-features --no-fail-fast: 9673 passed. 65 failed, all outside this change. They were caused by the sandbox: running as root (read-onlychmodfixtures can't fail a write) and the disk filling up mid-run (self-update / notifier fixtures hitENOSPC). CI is the authority for those.cargo fmt --all -- --check: the changed lines are fmt-clean.mainitself is not rustfmt-clean repo-wide, and CI doesn't run fmt.Follow-ups
hatchexecutable planted in the scanned project #613: an architecture test banningCommand::new("<literal>")in production code outsideutils/process.rs. Not included here, to keep this change focused.🤖 Generated with Claude Code
https://claude.ai/code/session_01BbXFWxz5BKEPH4xmF5VK7y
Note
Medium Risk
Changes subprocess invocation during PyPI Hatch vendoring in a scanned repo; behavior for legitimate Hatch on PATH should be unchanged, but spawn resolution rules are security-sensitive.
Overview
Fixes a security issue where vendored Hatch support could run a
hatchbinary committed inside the scanned project during thehatch --versioncapability probe.The probe now follows the same pattern as other CLI spawns:
resolve_tool_withpickshatchonly on absolutePATHentries, andcommand_forruns that resolved path (with the same cwd, timeout, and version ≥1.2 gate). Missinghatchstill surfacespypi_hatch_unsupported. Logic is refactored intorequire_environment_context_support_withso tests can injectPATH. Unix regression tests cover plantedhatchunder./emptyPATHand a control case withhatchon an absolute bin dir.Reviewed by Cursor Bugbot for commit e7466ea. Configure here.
Generated by Claude Code